Editing and debugging software program code is the process of writing and modifying instructions in a programming language, such as C++, C#, VB.NET, and other languages. Some programming environments even provide building blocks for programs that are visual in nature such that the program author may not be aware of or directly interact with an underlying programming language. Editing and debugging is often time consuming, as it involves running a software program many times, inspecting the results up to a particular point for errors, solving any errors by modifying the program code, and running the program again. Software testing seeks to subject a software program to real world usage conditions to find potential errors in the software program so the errors can be corrected before delivering the program to customers.
Development environments, such as the MICROSOFT™ VISUAL STUDIO™ development environment, provide many features for building, testing, and debugging software programs. One feature of modern development environments is “edit and continue” which allows a software developer to modify software code directly in a debugger and have those modifications reflected during the debugging session. Behind the scenes the development environment may make the received change, recompile the program code, and re-run the program up to the point of the previous execution. Repeated execution may entail recomputing previously determined results.
Caching seeks to save results of computations on data so that future requests for the results can be satisfied from a cache rather than through repeated computation of the results. Caching can occur at many levels, including inside computer processors (e.g., L1 and L2 cache), within computer system memory, in networking hardware (e.g., a buffer in a network card or an Internet proxy), and so forth. Caching is often difficult because to be effective it is often useful for the software developer to be involved in choosing what, when, and where to cache data.
Complex programs are often written by breaking a problem down into a series of simple steps that can be more easily authored, verified, and reasoned about. The downside to such an approach is that typically in order to compute step N+1, steps 1 through N are recomputed, resulting in longer computation with the addition of each step. Programming languages often include mechanisms that can be used to cache results in order to improve performance, but these caches are typically required to be explicit, and typically do not cross execution boundaries. For example, a function written in C# or the JAVA™ programming language that reads data from a database will typically read the same data from the database upon every invocation of the function unless the program takes explicit steps to cache the data. Additionally, repeated executions of such a program will read the same data from the database, unless the program has taken explicit steps to cache the data outside of the memory of the program.
Many language environments typically involve a translation from source code to executable code, which usually implies that edits or changes to the source code demand the executable code to be regenerated, which in turn means that the program is restarted after the changes. In such environments and in the absence of explicit caching, previous computation is lost and is recomputed. For example, consider a C++ program that reads a large file of numbers and computes the sum. In order to have the program also compute the average, the source program will be modified and recompiled. Then, the program restarts and the file is read into memory again. Depending on the size of the data, this can introduce substantial delays into the process of authoring program code, and can create a substantial performance hit to resources such as processors, networking hardware, databases, and so forth.